package com.tiger.pulldata.openAccount;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.tiger.cache.RedisService;
import com.tiger.db.entity.SchoolDept;
import com.tiger.db.entity.Student;
import com.tiger.db.entity.Teacher;
import com.tiger.pulldata.Db;
import com.tiger.pulldata.openAccount.type.DataApiResult;
import com.tiger.pulldata.openAccount.type.OpenAccountConfig;
import com.tiger.pulldata.openAccount.type.TokenApiResult;
import com.tiger.utils.Utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class OpenAccountService {


    @Value("${pullTeacherTaskQueueKey}")
    public String pullTeacherTaskQueueKey;
    @Value("${pullStudentTaskQueueKey}")
    public String pullStudentTaskQueueKey;

    public final OpenAccountConfig openAccountConfig;


    public String token;
    private final Db db;
    private final RedisService redisService;

    public OpenAccountService(OpenAccountConfig openAccountConfig, Db db, RedisService redisService) {
        this.openAccountConfig = openAccountConfig;
        this.db = db;
        this.redisService = redisService;
    }

    //获取api的token
    public void getApiJwtToken() {
        System.out.println("任务执行时间token: " + LocalDateTime.now());

        RestTemplate template = new RestTemplate();

        HashMap<String, Object> params = new HashMap<>();
        params.put("appid", openAccountConfig.getAppid());
        params.put("secret", openAccountConfig.getSecret());

        try{
            TokenApiResult r = template.postForEntity(openAccountConfig.getTokenUrl(), params, TokenApiResult.class).getBody();
            if(r.getStatus() != 200) return;
            token = r.getData();
            redisService.template.opsForValue().set(openAccountConfig.getTokenKey(), token);
        }catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /***
     * 监听拉取老师的任务
     */
    @Async
    public void onPullTeacherTask() {
        long sleepTime = 1000 * 10;
        while (true) {
            try {
                String flag = redisService.template.opsForList().rightPop(pullTeacherTaskQueueKey);
                if(flag == null) {
                    // 休眠一段时间，例如100毫秒
                    Thread.sleep(sleepTime);
                }else {
                    System.out.println(flag);
                    pullTeacher(flag);
                }

            } catch (Exception e) {

            }

        }
    }



    /***
     * 监听拉取学生的任务
     */
    @Async
    public void onPullStudentTask() {
        long sleepTime = 1000 * 10;
        while (true) {
            try {
                String flag = redisService.template.opsForList().rightPop(pullStudentTaskQueueKey);
                if(flag == null) {
                    // 休眠一段时间
                    Thread.sleep(sleepTime);
                }else {

                    System.out.println(flag);

                    pullStudent(flag);
                }




            } catch (Exception e) {

            }



        }
    }

    @Async
    public void pullDepts(){


        RestTemplate restTemplate = new RestTemplate();

        JSONObject jsonStr = new JSONObject();
        jsonStr.put("id", openAccountConfig.getDeptApiId());

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openAccountConfig.getApiUrl());
        builder.queryParam("token", token);
        builder.queryParam("jsonStr", jsonStr.toJSONString());


        DataApiResult r = restTemplate.getForEntity(builder.build().encode().toUri(), DataApiResult.class).getBody();

        if(r.getStatus() != 200) return;
        List<HashMap<String, String>> list = r.getData().getList();

        Collections.sort(list, new Comparator<Map<String, String>>() {
            @Override
            public int compare(Map<String, String> o1, Map<String, String> o2) {
                int level1 = Integer.parseInt(o1.getOrDefault("DWLEVEL", "0")); // 使用默认值以防万一
                int level2 = Integer.parseInt(o2.getOrDefault("DWLEVEL", "0"));
                return Integer.compare(level1, level2);
            }
        });

        for(HashMap<String, String> row : list) {
            String code = row.get("DWH"); //原始的id
            int level = Integer.parseInt(row.get("DWLEVEL")); //排序

            if(level == 1) continue;

            level -= 1;


            SchoolDept old = db.schoolDept.getOne(new LambdaQueryWrapper<SchoolDept>().eq(SchoolDept::getCode, code));
            if(old == null) { //还没有的
                SchoolDept dept = new SchoolDept();
                dept.setName(row.get("name"));
                dept.setLevel(level);
                dept.setCode(code);
                dept.setName(row.get("DWMC"));

                if(level > 1) { //非顶级
                    SchoolDept parentDept = db.schoolDept.getOne(new LambdaQueryWrapper<SchoolDept>().select(SchoolDept::getId, SchoolDept::getTopId).eq(SchoolDept::getCode, row.get("LSDWH")));


                    dept.setParentId(parentDept.getId());
                    dept.setTopId(parentDept.getTopId() == 0 ? parentDept.getId() : parentDept.getTopId());
                }

                db.schoolDept.save(dept);
            }else {
                String name = row.get("name");
                if(!Objects.equals(old.getName(), name)) {
                    old.setName(name);
                    db.schoolDept.updateById(old);
                }
            }

        }

        System.out.println("------ 拉取部门结束 ---------");

    }

    @Async
    public void pullStudent(String flag) throws IOException {
        int pageIndex = 1;
        int pageSize = 3000;

        RestTemplate restTemplate = new RestTemplate();

        JSONObject jsonStr = new JSONObject();
        jsonStr.put("id", openAccountConfig.getOrdinaryStuApiId());
        jsonStr.put("pageSize", pageSize);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openAccountConfig.getApiUrl());
        builder.queryParam("token", token);

        if(flag != null) {
            redisService.template.opsForValue().set(flag, "0", 60 * 20, TimeUnit.SECONDS);
        }


        //拉取本专科生
        while (true) {
            jsonStr.put("pageIndex", pageIndex);
            pageIndex ++;

            builder.replaceQueryParam("jsonStr", jsonStr.toJSONString());

            DataApiResult r = restTemplate.getForEntity(builder.build().encode().toUri(), DataApiResult.class).getBody();
            if(r == null) break;
            if(r.getStatus() != 200) break;

            System.out.println("--------------------获取到数据了--------------");


            List<HashMap<String, String>> list = r.getData().getList();
            int size = list.size();
            if(size == 0) break;

            r = null;

            HashMap<String, HashMap<String, String>> xhToRow = new HashMap<>();

            List<String> xhs = new ArrayList<>();

            for(HashMap<String, String> row : list) {

                System.out.println(row);

                xhs.add(row.get("XH"));
                xhToRow.put(row.get("XH"), row);
            }



            //需要新增的
            List<Student> newStus = new ArrayList<>();

            //需要更改的
            List<Long> updateIds = new ArrayList<>();

            List<Student> students = db.student.list(new LambdaQueryWrapper<Student>().select(Student::isGraduateStatus, Student::getId, Student::getXh).eq(Student::getType, 1).in(Student::getXh, xhs));

            HashMap<String, Student> xhToStus = new HashMap<>();

            for(Student stu : students) {
                xhToStus.put(stu.getXh(), stu);
            }

            students = null;

            for(String xh : xhs) {
                HashMap<String, String> row = xhToRow.get(xh);
                boolean graduateStatus = Objects.equals(row.get("BYF"), "1");

                if(xhToStus.containsKey(xh)) { //已经存在了
                    Student student = xhToStus.get(xh);
                    if(student.isGraduateStatus() != graduateStatus) { //已经毕业了
                        updateIds.add(student.getId());
                    }

                }else { //不存在的
                    if(graduateStatus) continue; //毕业的不要

                    System.out.println(row);

                    Student student = new Student();
                    student.setSource(1);
                    student.setXh(xh);
                    student.setName(row.get("XM"));
                    student.setSex(Integer.parseInt(row.get("XBM")));
                    student.setDeptCode(row.get("YXSH"));
                    student.setGrade(row.get("SZNJ"));
                    student.setClassNo(row.get("SZBH"));
                    student.setMajorCode(row.get("ZYM"));
                    student.setType(1);
                    if(!Objects.equals(row.get("XZ"), "")) {
                        student.setXz(row.get("XZ"));
                    }
                    student.setGraduateStatus(graduateStatus);

                    newStus.add(student);
                }
            }

            //新增的
            if(!newStus.isEmpty()) {
                db.student.saveBatch(newStus);
            }

            //更新毕业状态
            if(!updateIds.isEmpty()) {
                LambdaUpdateWrapper<Student> wrap = new LambdaUpdateWrapper<>();
                wrap.in(Student::getId, updateIds);
                wrap.set(Student::isGraduateStatus, true);
                db.student.update(wrap);
            }

            if(size < pageSize) break;
        }

        //拉取研究生
        pageIndex = 1;
        jsonStr.put("id", openAccountConfig.getPostgraduateStuApiId());

        System.out.println("---------------拉取研究生-----------");

        while (true) {
            jsonStr.put("pageIndex", pageIndex);
            pageIndex ++;

            builder.replaceQueryParam("jsonStr", jsonStr.toJSONString());

            DataApiResult r = restTemplate.getForEntity(builder.build().encode().toUri(), DataApiResult.class).getBody();
            if(r == null) break;
            if(r.getStatus() != 200) break;

            List<HashMap<String, String>> list = r.getData().getList();
            int size = list.size();
            if(size == 0) break;

            r = null;

            HashMap<String, HashMap<String, String>> xhToRow = new HashMap<>();

            List<String> xhs = new ArrayList<>();

            for(HashMap<String, String> row : list) {
                xhs.add(row.get("XH"));
                xhToRow.put(row.get("XH"), row);
            }

            r = null;

            //需要新增的
            List<Student> newStus = new ArrayList<>();

            //需要更改的
            List<Long> updateIds = new ArrayList<>();

            List<Student> students = db.student.list(new LambdaQueryWrapper<Student>().select(Student::isGraduateStatus, Student::getId, Student::getXh).eq(Student::getType, 2).in(Student::getXh, xhs));

            HashMap<String, Student> xhToStus = new HashMap<>();

            for(Student stu : students) {
                xhToStus.put(stu.getXh(), stu);
            }

            students = null;

            for(String xh : xhs) {
                HashMap<String, String> row = xhToRow.get(xh);

                boolean graduateStatus = Objects.equals(row.get("BYF"), "1");

                if(xhToStus.containsKey(xh)) { //已经存在了
                    Student student = xhToStus.get(xh);
                    if(student.isGraduateStatus() != graduateStatus) { //已经毕业了
                        updateIds.add(student.getId());
                    }

                }else { //不存在的
                    if(graduateStatus) continue; //毕业的不要


                    Student student = new Student();
                    student.setSource(1);
                    student.setXh(xh);
                    student.setName(row.get("XM"));
                    student.setSex(Integer.parseInt(row.get("XBM")));
                    student.setDeptCode(row.get("YXSH"));
                    student.setGrade(row.get("SZNJ"));
                    student.setClassNo(row.get("SZBH"));
                    student.setMajorCode(row.get("ZYM"));
                    student.setType(2);

                    if(!Objects.equals(row.get("XZ"), "")) {
                        student.setXz(row.get("XZ"));
                    }


                    student.setGraduateStatus(graduateStatus);

                    newStus.add(student);
                }
            }

            //新增的
            if(!newStus.isEmpty()) {
                db.student.saveBatch(newStus);
            }

            //更新毕业状态
            if(!updateIds.isEmpty()) {
                LambdaUpdateWrapper<Student> wrap = new LambdaUpdateWrapper<>();
                wrap.in(Student::getId, updateIds);
                wrap.set(Student::isGraduateStatus, true);
                db.student.update(wrap);
            }

            if(size < pageSize) break;
        }

        if(flag != null) {
            redisService.template.opsForValue().set(flag, "1", 20, TimeUnit.SECONDS);
        }

        System.out.println("拉取学生结束");

    }

    //拉取教师
    @Async
    public void pullTeacher(String flag) {
        System.out.println("------------------拉取老师----------");

        if(flag != null) {
            redisService.template.opsForValue().set(flag, "0", 60 * 20, TimeUnit.SECONDS);
        }

        int pageIndex = 1;
        int pageSize = 1000;

        RestTemplate restTemplate = new RestTemplate();

        JSONObject jsonStr = new JSONObject();
        jsonStr.put("id", openAccountConfig.getTeacherApiId());
        jsonStr.put("pageSize", pageSize);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(openAccountConfig.getApiUrl());
        builder.queryParam("token", token);


        while (true) {
            jsonStr.put("pageIndex", pageIndex);
            pageIndex ++;

            builder.replaceQueryParam("jsonStr", jsonStr.toJSONString());
            URI uri = builder.build().encode().toUri();
            DataApiResult r = restTemplate.getForEntity(uri, DataApiResult.class).getBody();
            if(r == null || r.getStatus() != 200) break;


            List<HashMap<String, String>> list = r.getData().getList();
            int size = list.size();
            if(size == 0) break;

            r = null;

            List<String> ghs = new ArrayList<>();
            HashMap<String, Teacher> ghToTeacherMap = new HashMap<>();


            for(HashMap<String, String> row : list) {
                String DQZTM = row.get("DQZTM").trim(); //在职状态码 3
                String gh = row.get("GH");
                ghs.add(gh);

                Teacher teacher = new Teacher();
                teacher.setSource(1);
                teacher.setGh(gh);
                teacher.setName(row.get("XM"));

                teacher.setJobStatusCode(DQZTM);

                teacher.setSex(Integer.parseInt(row.get("XBM")));
                teacher.setDeptCode(row.get("DWH"));
                teacher.setDept(row.get("DWMC"));
                teacher.setNation(row.get("MZ"));
                teacher.setNationCode(row.get("MZM"));
                teacher.setTitleLevel(row.get("ZCDJ"));
                teacher.setPoliticalCode(row.get("ZZMMM"));
                teacher.setPoliticalStatus(row.get("ZZMM"));

                teacher.setJobStatus(row.get("DQZT"));
                teacher.setTechnicalTitleCode(row.get("JSZJM"));
                teacher.setBzType(row.get("BZLB"));
                teacher.setStaffTypeCode(row.get("JZGLB"));
                teacher.setStaffType(row.get("JZGLBM"));
                teacher.setTitle(row.get("ZCMC"));
                teacher.setEduCode(row.get("ZGXLM"));
                teacher.setPositionLevel(row.get("ZWJB"));
                teacher.setCardDate(row.get("FKRQ"));
                teacher.setEmployDate(row.get("LXRQ"));
                teacher.setJobPost(row.get("GW"));
                teacher.setJobPostCode(row.get("GWLBM"));
                teacher.setCardExpire(row.get("YXRQ"));
                teacher.setCardNo(row.get("CARDNO"));
                teacher.setPosition(row.get("ZWMC"));
                teacher.setTel(row.get("TEL"));

                ghToTeacherMap.put(gh, teacher);

            }


            List<Teacher> rows = db.teacher.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getGh, ghs));



            try {
                for(Teacher row : rows) {
                    Teacher t = ghToTeacherMap.get(row.getGh());

                    if(t != null) { //已经存在的了
                        Utils.copyPropertiesIgnoreNull(t, row);
                        ghToTeacherMap.remove(row.getGh());

                        db.teacher.updateById(row);
                    }else if(!Objects.equals(t.getJobStatusCode(), "3")) { //离职的不要
                        ghToTeacherMap.remove(row.getGh());
                    }
                }

                if(!ghToTeacherMap.isEmpty()) {
                    db.teacher.saveBatch(ghToTeacherMap.values());
                }
            }catch (Exception E) {
                System.out.println(E.getMessage());
            }

            if(size < pageSize) break;
        }

        if(flag != null) {
            redisService.template.opsForValue().set(flag, "1", 20, TimeUnit.SECONDS);
        }


        System.out.println("拉取老师结束");

    }



}
